package com.ruoyi.project.shortUrl.url.service.impl;

import java.util.Date;
import java.util.List;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang3.StringUtils;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.TermQueryBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.ruoyi.common.exception.BusinessException;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.ElasticSearchUtils;
import com.ruoyi.common.utils.IpUtils;
import com.ruoyi.common.utils.ServletUtils;
import com.ruoyi.common.utils.ShortUrlCodeGenerator;
import com.ruoyi.common.utils.security.ShiroUtils;
import com.ruoyi.common.utils.text.Convert;
import com.ruoyi.project.shortUrl.cache.ShortCodeCache;
import com.ruoyi.project.shortUrl.cache.ShortCodeCacheEntity;
import com.ruoyi.project.shortUrl.config.domain.ShortConfig;
import com.ruoyi.project.shortUrl.config.enums.ShortUrlOpenWay;
import com.ruoyi.project.shortUrl.config.service.ShortConfigService;
import com.ruoyi.project.shortUrl.url.domain.ShortUrl;
import com.ruoyi.project.shortUrl.url.mapper.ShortUrlMapper;
import com.ruoyi.project.shortUrl.url.service.IDomainOfShortUrlService;
import com.ruoyi.project.shortUrl.url.service.IShortUrlService;
import com.ruoyi.project.shortUrl.util.ShortUrlRoleKey;
import com.ruoyi.project.system.user.domain.User;
import com.ruoyi.project.system.user.service.IUserService;

/**
 * 短链接Service业务层处理
 * 
 * @author ruoyi
 * @date 2020-03-29
 */
@Service
public class ShortUrlServiceImpl implements IShortUrlService 
{
	@Autowired
	private ShortCodeCache shortCodeCache;
	
    @Autowired
    private ShortUrlMapper shortUrlMapper;
    
//    @Autowired
//    private CheckShortCode checkShortCode;
    
    @Autowired
    private ShortConfigService shortConfigService;
    
    @Autowired
    private IUserService userService;
    
    @Autowired
    private IDomainOfShortUrlService domainService;

    /**
     * 查询短链接
     * 
     * @param shortCode 短链接ID
     * @return 短链接
     */
    @Override
    public ShortUrl selectShortUrlById(String shortCode)
    {
        return shortUrlMapper.selectShortUrlById(shortCode);
    }

    /**
     * 查询短链接列表
     * 
     * @param shortUrl 短链接
     * @return 短链接
     */
    @Override
    public List<ShortUrl> selectShortUrlList(ShortUrl shortUrl)
    {
        return shortUrlMapper.selectShortUrlList(shortUrl);
    }


    /**
     * 修改短链接
     * 
     * @param shortUrl 短链接
     * @return 结果
     */
    @Override
    public int updateShortUrl(ShortUrl shortUrl)
    {
    	shortCodeCache.update(new ShortCodeCacheEntity(shortUrl));
        return shortUrlMapper.updateShortUrl(shortUrl);
    }

    /**
     * 删除短链接对象
     * 
     * @param ids 需要删除的数据ID
     * @return 结果
     */
    @Override
    public int deleteShortUrlByIds(String ids)
    {
    	try {
			String[] delIds = Convert.toStrArray(ids);
			if(delIds!=null && delIds.length>0) {
				for(String id:delIds) {
					shortCodeCache.del(id);
				}
			}
		} catch (Exception e) {
		}
        return shortUrlMapper.deleteShortUrlByIds(Convert.toStrArray(ids));
    }

    /**
     * 删除短链接信息
     * 
     * @param shortCode 短链接ID
     * @return 结果
     */
    @Override
    public int deleteShortUrlById(String shortCode)
    {
    	shortCodeCache.del(shortCode);
        return shortUrlMapper.deleteShortUrlById(shortCode);
    }
    
    @Override
    public void deleteShortUrlByUserId(Long userId)
    {
    	ShortUrl filter = new ShortUrl();
		filter.setCreateUserId(userId.toString());
		List<ShortUrl> shorts = selectShortUrlList(filter);
		for(ShortUrl s:shorts) {
			deleteShortUrlById(s.getShortCode());
		}
    }

    @Override
	public int createShortUrl(String userType, ShortUrl shortUrl, int expireDay) {
		int maxSize = 0;
				
		if(StringUtils.isBlank(userType)) {
			throw new BusinessException("创建失败，用户类型未知！");
		}
		User loginUser = null;
		switch (userType) {
		//注册用户
		case ShortUrlRoleKey.ADMIN:
			maxSize = -1;
			loginUser = ShiroUtils.getSysUser();
			break;
					
		//注册用户
		case ShortUrlRoleKey.REGISTER:
			maxSize = shortConfigService.getREGISTER_DEFAULT_SHORT_LIMIT_SIZE();
			expireDay = shortConfigService.getREGISTER_DEFAULT_SHORT_EXPIRE_TIME();
			loginUser = ShiroUtils.getSysUser();
			break;
			
		//默认非注册用户
		default: 
			maxSize = shortConfigService.getVISITOR_SHORT_LIMIT_SIZE();
			expireDay = shortConfigService.getVISITOR_SHORT_EXPIRE_TIME();
			HttpServletRequest request = ServletUtils.getRequest();
			String ip = IpUtils.getIpAddr(request);
			User select = userService.selectUserByLoginName(ip);
			if(select==null) {
				User user = new User();
				user.setLoginName(ip);
				Long[] roleIds = {ShortUrlRoleKey.getNotRegisterRole().getRoleId()};
				user.setRoleIds(roleIds);
				//非注册用户停用
				user.setStatus("1");
				user.setCreateBy("admin");
				user.setRemark("非注册用户");
				user.setUserName(ip);
				userService.insertUser(user);
				select = user;
			}
			
			loginUser = select;
			break;
		}
		
		
		if(maxSize!=-1 && (shortUrlMapper.countByCreateUserId(loginUser.getUserId().toString())+1)>maxSize) {
			throw new BusinessException("超出最大数量限制！");
		}
		
		expireDay = expireDay<=0?-1:expireDay;
		if(expireDay == -1) {
    		shortUrl.setExpirationTime(null);
    	}else {
    		Date expireDate = DateUtils.addDays(DateUtils.getNowDate(), expireDay);
    		shortUrl.setExpirationTime(DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD, expireDate));
    	}
		
    	String shortCode = ShortUrlCodeGenerator.getShortUrl(loginUser.getUserId().toString(), shortUrl.getTargetUrl());
    	
    	ShortUrl exist = selectShortUrlById(shortCode);
    	if(exist==null) {
    		shortUrl.setShortCode(shortCode);
            shortUrl.setCreated(new Date().getTime());
            shortUrl.setCreateBy(loginUser.getLoginName());
            shortUrl.setCreateUserId(loginUser.getUserId().toString());
            
            if(StringUtils.isBlank(shortUrl.getMainDomain())) {
            	shortUrl.setMainDomain(domainService.selectRadom().getDomain());
            }
            
            shortCodeCache.add(new ShortCodeCacheEntity(shortUrl));
        	return shortUrlMapper.insertShortUrl(shortUrl);
    	}else {
			throw new BusinessException("用户["+loginUser.getLoginName()+"]已经创建了此目标链接的短链["+shortCode+"]，请不要重复添加！");
		}
	}
    
    @Override
	public String createShortUrlReturnShortUrl(String userType, ShortUrl shortUrl, int expireDay, String openWay) {
		String result = "";
		
    	int maxSize = 0;
				
		if(StringUtils.isBlank(userType)) {
			throw new BusinessException("创建失败，用户类型未知！");
		}
		User loginUser = null;
		switch (userType) {
		//注册用户
		case ShortUrlRoleKey.ADMIN:
			maxSize = -1;
			loginUser = ShiroUtils.getSysUser();
			break;
					
		//注册用户
		case ShortUrlRoleKey.REGISTER:
			maxSize = shortConfigService.getREGISTER_DEFAULT_SHORT_LIMIT_SIZE();
			expireDay = shortConfigService.getREGISTER_DEFAULT_SHORT_EXPIRE_TIME();
			loginUser = ShiroUtils.getSysUser();
			break;
			
		//默认非注册用户
		default: 
			userType = ShortUrlRoleKey.NOT_REGISTER;
			maxSize = shortConfigService.getVISITOR_SHORT_LIMIT_SIZE();
			expireDay = shortConfigService.getVISITOR_SHORT_EXPIRE_TIME();
			HttpServletRequest request = ServletUtils.getRequest();
			String ip = IpUtils.getIpAddr(request);
			User select = userService.selectUserByLoginName(ip);
			if(select==null) {
				User user = new User();
				user.setLoginName(ip);
				Long[] roleIds = {ShortUrlRoleKey.getNotRegisterRole().getRoleId()};
				user.setRoleIds(roleIds);
				//非注册用户停用
				user.setStatus("1");
				user.setCreateBy("admin");
				user.setRemark("非注册用户");
				user.setUserName(ip);
				userService.insertUser(user);
				select = user;
			}
			
			loginUser = select;
			break;
		}
		
		
		if(maxSize!=-1 && (shortUrlMapper.countByCreateUserId(loginUser.getUserId().toString())+1)>maxSize) {
			throw new BusinessException("超出最大数量限制！"+(ShortUrlRoleKey.NOT_REGISTER.equals(userType)?"注册后可以继续使用！":""));
		}
		
		expireDay = expireDay<=0?-1:expireDay;
		if(expireDay == -1) {
    		shortUrl.setExpirationTime(null);
    	}else {
    		Date expireDate = DateUtils.addDays(DateUtils.getNowDate(), expireDay);
    		shortUrl.setExpirationTime(DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD, expireDate));
    	}
		
    	String shortCode = ShortUrlCodeGenerator.getShortUrl(loginUser.getUserId().toString()+System.currentTimeMillis(), shortUrl.getTargetUrl());
    	ShortUrl exist = selectShortUrlById(shortCode);
		if(exist!=null) {
			return exist.getMainDomain()+"/"+exist.getShortCode();
		}else{
    		shortUrl.setShortCode(shortCode);
            shortUrl.setCreated(new Date().getTime());
            shortUrl.setCreateBy(loginUser.getLoginName());
            shortUrl.setCreateUserId(loginUser.getUserId().toString());
            if(StringUtils.isNotBlank(openWay)) {
            	shortUrl.setOpenWay(ShortUrlOpenWay.getEnum(openWay).toString());
            }else {
            	ShortConfig target_url_open_way = shortConfigService.getConfig("target_url_open_way");
            	if(target_url_open_way!=null) {
            		shortUrl.setOpenWay(ShortUrlOpenWay.getEnum(target_url_open_way.getValue()).toString());
            	}
            }
            
            if(StringUtils.isBlank(shortUrl.getMainDomain())) {
            	shortUrl.setMainDomain(domainService.selectRadom().getDomain());
            }
            
            shortCodeCache.add(new ShortCodeCacheEntity(shortUrl));
        	shortUrlMapper.insertShortUrl(shortUrl);
        	
        	result = shortUrl.getMainDomain()+"/"+shortUrl.getShortCode();
    	}
    	
    	return result;
	}
	
	@Override
	public int editShortUrl(User loginUser, String shortCode, String targetUrl, Integer expireDay) {
		ShortUrl shortUrl = new ShortUrl();
		shortUrl.setShortCode(shortCode);
		if(loginUser!=null && loginUser.isAdmin() && expireDay!=null) {
			expireDay = expireDay<=0?-1:expireDay;
			if(expireDay == -1) {
	    		shortUrl.setExpirationTime(null);
	    	}else {
	    		Date expireDate = DateUtils.addDays(DateUtils.getNowDate(), expireDay);
	    		shortUrl.setExpirationTime(DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD, expireDate));
	    	}
		}
		shortUrl.setTargetUrl(targetUrl);
		shortUrl.setModified(DateUtils.getNowDate().getTime());
		
		shortCodeCache.update(new ShortCodeCacheEntity(shortUrl));
		return shortUrlMapper.updateShortUrl(shortUrl);
	}

	@Override
	public int countAll() {
		return shortUrlMapper.countAll();
	}

	@Override
	public int deleteShortUrlByIExpireDate(String yymmdd) {
		
		shortUrlMapper.deleteShortUrlByIExpireDate(yymmdd);
		//清楚es
        TermQueryBuilder query = QueryBuilders.termQuery("expirationTime", yymmdd);
        ElasticSearchUtils.deleteByQuery(ShortCodeCache.index, query);
//		System.out.println(deleted);
        return 1;
	}

//	@Override
//	@Async
//	public void insertRequestLog(HttpServletRequest request, ShortCodeCacheEntity cacheEntity) {
//		UserAgent userAgent = UserAgent.parseUserAgentString(request.getHeader("User-Agent"));
//        String ip = IpUtils.getIpAddr(request);
//        String address = AddressUtils.getRealAddressByIP(ip);
//        // 获取客户端操作系统
//        String os = userAgent.getOperatingSystem().getName();
//        // 获取客户端浏览器
//        String browser = userAgent.getBrowser().getName();
//        // 封装对象
//        ShortUrlRequestLog shortUrlRequestLog = new ShortUrlRequestLog();
//        shortUrlRequestLog.setIpaddr(ip);
//        shortUrlRequestLog.setLoginLocation(address);
//        shortUrlRequestLog.setBrowser(browser);
//        shortUrlRequestLog.setOs(os);
//        shortUrlRequestLog.setShortCode(cacheEntity.getShortCode());
//        shortUrlRequestLog.setCreateUserId(cacheEntity.getCreateUserId());
//        shortUrlRequestLog.setRequestTime(DateUtils.getNowDate());
//        // 插入数据
//        shortUrlRequestLogService.insertShortUrlRequestLog(shortUrlRequestLog);
//	}
}
